/**
 * ReportGear(2011)
 */
package com.reportgear.report.model.auxiliary;

import java.util.ArrayList;
import java.util.List;

import net.abbp.core.api.ICloneable;

/**
 * 列属性列表
 * 
 * @version 1.0 2011-3-11
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 * 
 */
public class ColumnPropList implements ICloneable<ColumnPropList> {
    private List<ColumnProperty> elements;

    public ColumnPropList() {
        this.elements = new ArrayList<ColumnProperty>();
    }

    /**
     * 构造函数
     * 
     * @param defaultValue
     *            默认宽度
     * @param size
     *            大小
     */
    public ColumnPropList(int size) {
        this.elements = new ArrayList<ColumnProperty>(size);

        for (int i = 0; i < size; i++) {
            this.elements.add(new ColumnProperty());
        }
    }

    /**
     * 设置行列类型
     * 
     * @param index
     *            索引
     * @param type
     *            行列类型
     */
    public void setType(int index, ColumnType type) {
        this.checkSize(index);

        this.elements.get(index).setType(type);
    }

    public ColumnType getType(int index) {
        return this.get(index).getType();
    }

    /**
     * 是否分组
     * 
     * @param index
     *            索引
     */
    public boolean isGroup(int index) {
        return this.get(index).isGroup();
    }

    /**
     * 设置行列分组
     * 
     * @param index
     *            索引
     * @param group
     *            是否分组
     */
    public void setGroup(int index, boolean group) {
        this.checkSize(index);

        this.elements.get(index).setGroup(group);
    }

    /**
     * 计算从0到toIndex之间所有值之和
     * 
     * @param toIndex
     *            目标索引
     * @return 和值
     */
    public int getRangeValueFromZero(int toIndex) {
        return getRangeValue(0, toIndex);
    }

    /**
     * 计算范围内所有值之和
     * 
     * @param fromIndex
     *            开始索引
     * @param toIndex
     *            终止索引
     * @return 和值
     */
    public int getRangeValue(int fromIndex, int toIndex) {
        int result = 0;
        int index1 = Math.max(0, Math.min(fromIndex, toIndex));
        int index2 = Math.max(fromIndex, toIndex);

        while (index1 < index2) {
            result += this.getWidth(index1);
            ++index1;
        }

        return ((fromIndex <= toIndex) ? result : -result);
    }

    /**
     * 获取达到指定和值时的索引
     * 
     * @param value
     *            和值
     * @return 索引
     */
    public int getValueIndex(int value) {
        return getValueIndex(value, 0);
    }

    /**
     * 获取达到指定和值时的索引
     * 
     * @param value
     *            和值
     * @param fromIndex
     *            起始所有
     * @return 索引
     */
    public int getValueIndex(int value, int fromIndex) {
        int temp = 0;
        for (int index = fromIndex;; ++index) {
            temp += this.getWidth(index);
            if (temp > value) {
                return index;
            }
        }
    }

    /**
     * 设置指定索引的值
     * 
     * @param index 索引
     * @param width 宽度
     */
    public void setWidth(int index, int width) {
        this.checkSize(index);

        this.elements.get(index).setWidth(width);
    }

    /**
     * 获取指定索引属性的值
     * 
     * @param index
     *            索引
     * @return 值
     */
    public int getWidth(int index) {
        return this.get(index).getWidth();
    }

    /**
     * 获取指定索引的值
     * 
     * @param index
     *            索引
     * @return 值
     */
    public ColumnProperty get(int index) {
        if ((index == -1) || (index >= this.elements.size())) {// 超过当前大小取默认值
            return ColumnProperty.DEFAULT_COLUMN_PROPERTY;
        }

        return this.elements.get(index);
    }

    /**
     * 获取所有元素列表
     * 
     * @return 所有元素列表
     */
    public List<ColumnProperty> getAllElements() {
        return this.elements;
    }

    /**
     * 清空列表
     */
    public void clear() {
        this.elements.clear();
    }

    /**
     * 增加对象到指定索引
     * 
     * @param index
     *            索引
     * @param element
     *            对象
     */
    public void add(int index, ColumnProperty element) {
        checkSize(index);
        this.elements.add(index, element);
    }

    /**
     * 增加对象
     * 
     * @param element
     *            对象
     */
    public void add(ColumnProperty element) {
        this.elements.add(element);
    }

    /**
     * 移除指定索引的对象
     * 
     * @param index
     *            索引
     * @return 对象
     */
    public void remove(int index) {
        if (this.elements.size() > index) {
            this.elements.remove(index);
        }
    }

    /**
     * 获取元素个数
     * 
     * @return 元素个数
     */
    public int size() {
        return this.elements.size();
    }

    /**
     * 是否可见
     * 
     * @param index
     *            索引
     * @return 是否可见
     */
    public boolean isVisible(int index) {
        return this.get(index).isVisible();
    }

    /**
     * 插入节点
     * 
     * @param fromIndex
     *            开始Index
     * @param prop
     *            属性
     */
    public void insert(int fromIndex, ColumnProperty prop) {
        insert(fromIndex, 1, prop);
    }

    /**
     * 插入节点
     * 
     * @param fromIndex
     *            起点
     * @param length
     *            长度
     * @param prop
     *            节点
     */
    public void insert(int fromIndex, int length, ColumnProperty prop) {
        if ((fromIndex < 0) || (length <= 0)) {
            return;
        }

        for (int i = 0; i < length; i++) {
            this.elements.add(fromIndex + i, prop);
        }
    }

    /**
     * 确保能够获取指定索引的值，如果不能则扩充
     * 
     * @param index 索引
     */
    public void checkSize(int index) {
        if (index >= this.elements.size()) {// 索引超过当前大小扩充对象
            for (int i = 0, len = index - this.elements.size() + 1; i < len; i++) {
                this.elements.add(new ColumnProperty());
            }
        }
    }

    @Override
    public ColumnPropList clone() {
        ColumnPropList propList = new ColumnPropList();

        for (ColumnProperty t : this.getAllElements()) {
            propList.add(t.clone());
        }

        return propList;
    }

    /**
     * @param index 索引
     * @return 类型字符串
     */
    public String getTypeStringShort(int index) {
        return "";
    }
}
